package com.gomcarter.frameworks.base.converter;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;

import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * Created by daibing on 2023/6/27.
 */
public class PropertyJacksonAnnotationIntrospector extends JacksonAnnotationIntrospector {
    private final boolean disableJsonProperty;
    private final List<String> excludeClassNamePrefixList;

    public PropertyJacksonAnnotationIntrospector(boolean disableJsonProperty, List<String> excludeClassNamePrefixList) {
        this.disableJsonProperty = disableJsonProperty;
        this.excludeClassNamePrefixList = Optional.ofNullable(excludeClassNamePrefixList).orElse(Collections.emptyList());
    }

    @Override
    protected <A extends Annotation> A _findAnnotation(Annotated ann, Class<A> annoClass) {
        // 没有禁用 @JsonProperty，直接走原始逻辑
        if (!disableJsonProperty) {
            return super._findAnnotation(ann, annoClass);
        }
        // 被注解对象不是成员，直接走原始逻辑
        if (!(ann instanceof AnnotatedMember)) {
            return super._findAnnotation(ann, annoClass);
        }
        // 在排除的类名前缀列表范围以内，直接走原始逻辑
        if (excludeClassNamePrefixList.stream().anyMatch(((AnnotatedMember) ann).getFullName()::startsWith)) {
            return super._findAnnotation(ann, annoClass);
        }
        // 禁用 @JsonProperty， 被注解对象是成员，不在排除范围内，并且字段有注解 JsonProperty，直接返回null即可
        if (annoClass == JsonProperty.class && ann.hasAnnotation(JsonProperty.class)) {
            return null;
        }
        // 其他，直接走原始逻辑
        return super._findAnnotation(ann, annoClass);
    }

}
